<?php
// +-------------------------------------------------------------------------------
// | DingZone [ A Rapid Development Framework For Dingtalk ]
// +-------------------------------------------------------------------------------
// | 企业模块 v1.0
// |
// | Copyright (c) 2014-2018 http://www.heimalanshi.com All rights reserved.
// | Author : Jie
// | Date : 2018-08-09
// +-------------------------------------------------------------------------------

namespace app\core\model;

use think\Cache;
use think\Db;
use think\Model;

class EnterpriseModule {

    const ENTERPRISE_MODULE_STATUS_NORMAL = 'normal';
    const ENTERPRISE_MODULE_STATUS_EXPIRED = 'expired';
    const ENTERPRISE_MODULE_STATUS_REVOKED = 'revoked';

    /**
     * 统计每个企业都有多少个模块
     *
     * @return false|\PDOStatement|string|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function groupCountByEid() {
        return self::_q()->field("enterprise_id, count(*) as cnt")->group("enterprise_id")->select();
    }

    /**
     * 查看模块被哪些企业使用了
     *
     * @param $mid
     * @return array
     */
    public static function getAllEidByMid($mid) {
        if (!$mid) {
            return [];
        }
        return self::_q()->where([
            'module_id' => $mid
        ])->column("enterprise_id");
    }

    /**
     * 查询企业开通了哪些模块
     *
     * @param $eid
     * @param $status
     * @return false|\PDOStatement|string|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getByEid($eid, $status = false) {
        $conditions = [
            'enterprise_id' => $eid
        ];
        if ($status) {
            $conditions['status'] = $status;
        }
        return self::_q()->where($conditions)->order("gmt_created desc")->select();
    }

    /**
     * 根据id获取
     *
     * @param $eid
     * @param $mid
     * @return array|false|mixed|\PDOStatement|string|Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getById($eid, $mid) {
        $key = "core.EnterpriseModule." . $eid . "." . $mid;
        $cm = Cache::get($key);
        if ($cm) {
            return $cm;
        }

        $cm = self::_q()->where([
            'enterprise_id' => $eid,
            'module_id' => $mid
        ])->find();
        if (empty($cm)) {
            return false;
        }

        $adminers = $cm['adminers'];
        $adminers = empty($adminers) ? [] : json_decode($adminers, true);
        $cm['adminers'] = $adminers;

        $accessers = $cm['accessers'];
        if (empty($accessers) || $accessers == "*") {
            $accessers = ['type' => '*'];
        } else if ($accessers == "adminOnly") {
            $accessers = ['type' => 'adminOnly'];
        } else {
            $accessers = json_decode($accessers, true);
        }
        $cm['accessers'] = $accessers;

        Cache::set($key, $cm);

        return $cm;
    }

    /**
     * 查询出某个企业的所有模块信息
     *
     * @param $eid
     * @param bool $status
     * @return false|static[]
     * @throws \think\exception\DbException
     */
    public static function listAll($eid, $status = false) {
        $condition = [
            'enterprise_id' => $eid
        ];
        if ($status != false) {
            $condition['status'] = $status;
        }
        $rows = self::_q()->where($condition)->order("sort desc")->select();
        foreach ($rows as &$row) {
            $row['module'] = SiteModule::getById($row['module_id']);
        }
        return $rows;
    }

    /**
     * 获取某个模块下的菜单链接(会将mid和eid塞入到链接参数中)
     *
     * @param $mid
     * @return array
     * @throws \think\exception\DbException
     */
    public static function getModuleMenus($mid) {
        $dao = new SiteModuleMenu();
        $moduleMenus = [];
        $moduleMenuObjs = $dao->where(['module_id' => $mid, 'type' => 'menu'])->order("sort desc")->select();
        foreach ($moduleMenuObjs as $moduleMenuObj) {
            $moduleMenu = $moduleMenuObj->getData();
            $link = $moduleMenu['link'];
            if ($link == '#' || empty($link)) {
                $link = "javascript:;";
            } else {
                if (strpos($link, '?') !== FALSE) {
                    $link .= "&";
                } else {
                    $link .= "?";
                }
                $link .= "mid=" . $mid;
            }
            $moduleMenu['link'] = $link;
            $moduleMenus[] = $moduleMenu;
        }

        // 按照树形结构组织
        $moduleMenus = remap($moduleMenus, "id");
        foreach ($moduleMenus as $id => $moduleMenu) {
            $parentId = fetch($moduleMenu, 'parent_id');
            if ($parentId) {
                if (!isset($moduleMenus[$parentId])) {
                    continue;
                }
                if (!isset($moduleMenus[$parentId]['sub'])) {
                    $moduleMenus[$parentId]['sub'] = [];
                }
                $moduleMenus[$parentId]['sub'][] = $moduleMenu;
                unset($moduleMenus[$id]);
            }
        }

        return $moduleMenus;
    }

    /**
     * 获取模块的前台入口链接地址
     *
     * @param $mid
     * @param $eid
     * @return array
     * @throws \think\exception\DbException
     */
    public static function getModuleEntries($mid, $eid) {
        $dao = new SiteModuleMenu();
        $moduleEntries = [];
        $moduleEntryObjs = $dao->where(['module_id' => $mid, 'type' => 'entry'])->order("sort desc")->select();
        foreach ($moduleEntryObjs as $moduleEntryObj) {
            $moduleEntry = $moduleEntryObj->getData();
            $link = $moduleEntry['link'];
            if (strpos($link, '?') !== FALSE) {
                $link .= "&";
            } else {
                $link .= "?";
            }
            $link .= "mid=" . $mid;
            $link .= "&eid=" . $eid;
            $moduleEntry['link'] = $link;
            $moduleEntries[] = $moduleEntry;
        }
        return $moduleEntries;
    }


    /**
     * 删除指定模块
     *
     * @param $mid
     * @return int
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     */
    public static function deleteByMid($mid) {
        return self::_q()->where(['module_id' => $mid])->delete();
    }

    /**
     * 更新模块信息
     *
     * @param $data
     * @param $mid
     * @param $eid
     * @return int|string
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     */
    public static function update($data, $mid, $eid) {
        $ret = self::_q()->where([
            'module_id' => $mid,
            'enterprise_id' => $eid
        ])->update($data);

        $key = "core.EnterpriseModule." . $eid . "." . $mid;
        Cache::rm($key);

        return $ret;
    }

    /**
     * 添加记录
     *
     * @param $data
     * @return int|string
     */
    public static function add($data) {
        $data['gmt_created'] = time();
        return self::_q()->insertGetId($data);
    }

    /**
     * 批量检查模块是否过期
     *
     * @param $enterpriseModules
     * @return mixed
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     */
    public static function batchCheckExpired($enterpriseModules) {
        foreach ($enterpriseModules as &$enterpriseModule) {
            self::checkExpired($enterpriseModule);
        }
        return $enterpriseModules;
    }

    /**
     * 检查模块是否过期
     *
     * @param $enterpriseModule
     * @return mixed
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     */
    public static function checkExpired(&$enterpriseModule) {
        if ($enterpriseModule['status'] != EnterpriseModule::ENTERPRISE_MODULE_STATUS_NORMAL) {
            return $enterpriseModule;
        }
        if (empty($enterpriseModule['expiry'])) {
            return $enterpriseModule;
        }
        if (time() > $enterpriseModule['expiry']) {
            // 模块过期了，更新状态
            self::update(
                ['status' => EnterpriseModule::ENTERPRISE_MODULE_STATUS_EXPIRED],
                $enterpriseModule['module_id'],
                $enterpriseModule['enterprise_id']
            );
            $enterpriseModule['status'] = EnterpriseModule::ENTERPRISE_MODULE_STATUS_EXPIRED;
        }
        return $enterpriseModule;
    }

    /**
     * @return \think\db\Query
     */
    private static function _q() {
        return Db::name("EnterpriseModule");
    }
}